// 
// MessageTab.cs
// 
// Copyright © 2009 Jiří Zárevúcky <zarevucky.jiri@gmail.com>
//
// MessageTab.cs is part of SpiderIM.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//

using System;
using System.Collections.Generic;
using Gtk;
using Glade;

using L=Galaxium.Protocol.Xmpp.Library;
using Galaxium.Protocol.Xmpp.Library;
using Galaxium.Protocol.Xmpp.Library.Messaging;
using Galaxium.Protocol.Xmpp.Library.Utility;
using Galaxium.Protocol.Xmpp.Library.Core;

// FIXME: Resend instead of Reply and Forward on outgoing messages.

// TODO: Alert when closing (losing changes)

// FIXME: multiple recipient support (multiple selected items in roster)

// FIXME: need's some cleanup

namespace Galaxium.Protocol.Xmpp.GtkGui.Messages
{
	public class MessageWindow
	{
		[Widget] private Window window = null;
		
		[Widget] private Label from_label = null;
		[Widget] private Entry from_entry = null;
		[Widget] private Entry to_entry = null;
		[Widget] private Entry subject_entry = null;
		[Widget] private TextView textview = null;
		[Widget] private Button reply_button = null;
		[Widget] private Button forward_button = null;
		[Widget] private Button send_button = null;

		private L.Client _client;
		private string   _thread;
		private int      _id;

		private static Dictionary<int, MessageWindow> s_opened =
			new Dictionary<int, MessageWindow> ();

		public static void Read (L.Client client, int id)
		{
			if (s_opened.ContainsKey (id)) {
				var win = s_opened [id];
				win.Present ();
			} else {
				var msg = client.MessageManager.GetMessageContent (id);
		
				new MessageWindow (client, msg.Source, msg.Destination, id,
				                   msg.Subject, msg.Body, msg.Thread, false);
			}
		}

		public static void ComposeNew (L.Client client, JabberID contact)
		{
			new MessageWindow (client, JabberID.Empty, contact, -1,
			                   String.Empty, String.Empty, null, true);
		}
		
		protected MessageWindow (L.Client client, JabberID from, JabberID to, int id,
		                         string subject, string body, string thread, bool compose)
		{
			_client = client;
			_thread = thread;
			_id = id;
			
			var gxml = new XML (null, "MessageWindow.glade", null, null);
			gxml.Autoconnect (this);

			if (compose)
				SetupCompose ();
			else
				SetupRead ();
			
			if (to != JabberID.Empty)
				to_entry.Text = to.Bare ();
			if (!compose && from != JabberID.Empty)
				from_entry.Text = from.Bare ();
			
			subject_entry.Text = subject;
			textview.Buffer.Text = body;

			send_button.Clicked += HandleSendClicked;
			forward_button.Clicked += HandleForwardClicked;
			reply_button.Clicked += HandleReplyClicked;

			if (_id > -1) {
				s_opened [id] = this;
				window.DeleteEvent += delegate { if (_id > -1) s_opened.Remove (_id); };
			}

			window.Title = String.IsNullOrEmpty (subject)
				? (compose ? "New Message" : "No Subject") : subject;

			window.Show ();
		}

		private void Present ()
		{
			window.Present ();
		}

		void HandleSendClicked (object sender, EventArgs e)
		{
			List<JabberID> recipients = new List<JabberID> ();
			foreach (var jid in to_entry.Text.Split (','))
				recipients.Add (new JabberID (jid.Trim ()));
			
			_client.MessageManager.Send (subject_entry.Text, textview.Buffer.Text,
			                             _thread, null, recipients.ToArray ());

			window.Destroy ();
		}

		void HandleForwardClicked (object sender, EventArgs e)
		{
			ForwardMessage ();
		}

		void HandleReplyClicked (object sender, EventArgs e)
		{
			ReplyToMessage ();
		}
		
		protected void ReplyToMessage ()
		{
			s_opened.Remove (_id);
			_id = -1;
			
			to_entry.Text = from_entry.Text;
			from_entry.Text = String.Empty;

			subject_entry.Text = "Re: " + subject_entry.Text;
			
			var header = "---- Original message ----\n\n";
			textview.Buffer.Text = "\n\n" + StringUtils.PrependLines (header + textview.Buffer.Text, "> ");
			
			SetupCompose ();
		}

		protected void ForwardMessage ()
		{
			s_opened.Remove (_id);
			_id = -1;

			var header = "---- Original message from " + from_entry.Text + " ----\n\n";
			
			from_entry.Text = to_entry.Text = String.Empty;
			subject_entry.Text = "Fwd: " + subject_entry.Text;
			
			textview.Buffer.Text = "\n\n" + StringUtils.PrependLines (header + textview.Buffer.Text, "> ");

			_thread = null;

			SetupCompose ();
		}
		
		private void SetupCompose ()
		{
			send_button.Show ();
			from_entry.IsEditable = true;
			to_entry.IsEditable = true;
			subject_entry.IsEditable = true;
			textview.Editable = true;
			
			from_label.Hide ();
			from_entry.Hide ();
			reply_button.Hide ();
			forward_button.Hide ();
		}

		private void SetupRead ()
		{
			from_label.Show ();
			from_entry.Show ();
			reply_button.Show ();
			forward_button.Show ();
			
			send_button.Hide ();
			from_entry.IsEditable = false;
			to_entry.IsEditable = false;
			subject_entry.IsEditable = false;
			textview.Editable = false;
		}
	}
}
